{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import sys\n",
    "import time\n",
    "import requests"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "POP20_CC = ('CN IN US ID BR PK NG BD RU JP '\n",
    "            'MX PH VN ET EG DE IR TR CD FR').split()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "BASE_URL = 'http://flupy.org/data/flags'\n",
    "DEST_DIR = 'downloads/'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def save_flag(img, filename):\n",
    "    path = os.path.join(DEST_DIR, filename)\n",
    "    with open(path, 'wb') as fp:\n",
    "        fp.write(img)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_flag(cc):\n",
    "    url = '{}/{cc}/{cc}.gif'.format(BASE_URL, cc=cc.lower())\n",
    "    resp = requests.get(url)\n",
    "    return resp.content"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def show(text):\n",
    "    print(text, end=' ')\n",
    "    sys.stdout.flush()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def download_many(cc_list):\n",
    "    for cc in sorted(cc_list):\n",
    "        image = get_flag(cc)\n",
    "        show(cc)\n",
    "        save_flag(image, cc.lower() + '.gif')\n",
    "\n",
    "    return len(cc_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "def main(download_many):\n",
    "    t0 = time.time()\n",
    "    count = download_many(POP20_CC)\n",
    "    elapsed = time.time() - t0\n",
    "    msg = '\\n{} flags downloaded in {:.2f}s'\n",
    "    print(msg.format(count, elapsed))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "BD BR CD CN DE EG ET FR ID IN IR JP MX NG PH PK RU TR US VN \n",
      "20 flags downloaded in 14.75s\n"
     ]
    }
   ],
   "source": [
    "main(download_many)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 使用concurrent.futures模块下载"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "from concurrent import futures"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "MAX_WORKERS = 20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "def download_one(cc):\n",
    "    image = get_flag(cc)\n",
    "    show(cc)\n",
    "    save_flag(image, cc.lower() + '.gif')\n",
    "    return cc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "def download_many(cc_list):\n",
    "    workers = min(MAX_WORKERS, len(cc_list))\n",
    "    with futures.ThreadPoolExecutor(workers) as executor:\n",
    "        res = executor.map(download_one, sorted(cc_list))\n",
    "    return sorted(list(res))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "BD INID FRDECN BREG     ET NGCD  RU VNMXTRPKPHIR      JP US \n",
      "['BD', 'BR', 'CD', 'CN', 'DE', 'EG', 'ET', 'FR', 'ID', 'IN', 'IR', 'JP', 'MX', 'NG', 'PH', 'PK', 'RU', 'TR', 'US', 'VN'] flags downloaded in 0.80s\n"
     ]
    }
   ],
   "source": [
    "main(download_many)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
